/**
 * @author 冷水
 * 创建时间：Apr 3, 20084:12:56 PM
 */
package com.hezuti.common.dao;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.util.Assert;

/**
 * @author 冷水 创建时间：Apr 3, 20084:12:56 PM
 */
public class HibernateSqlQuery implements Queryable {
	/**ORDER_ASC*/
	public static final boolean ORDER_ASC = true;
	/**ORDER_DESC*/
	public static final boolean ORDER_DESC = !ORDER_ASC;
	/**select*/
	private String select;
	/**orderList*/
	private List<OrderbyItem> orderList = new ArrayList<OrderbyItem>();
	
	private List<EntityItem> entityList = new ArrayList<EntityItem>();

	/**
	 * 
	 * @param name
	 * @param c
	 */
	@SuppressWarnings("unchecked")
	public void addEntityItem(String name, Class c) {
		entityList.add(new EntityItem(name, c));
	}
	/**
	 * 
	 * @param index
	 * @return
	 */
	public String getEntityName(Integer index) {
		return entityList.get(index).name;
	}
	/**
	 * 
	 * @param index
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Class getEntityClass(Integer index) {
		return entityList.get(index).cls;
	}
	/**
	 * 
	 * @return
	 */
	public Integer getEntitySize() {
		return entityList.size();
	}

	private String getRemovedSelect(String sql) {
		Assert.hasText(sql);
		int idx = sql.toLowerCase().indexOf("from");
		return idx == -1 ? sql : sql.substring(idx);
	}
	/**
	 * 
	 * @return
	 */
	public String getSelect() {
		return StringUtils.isEmpty(select) ? "" : select;
	}
	/**
	 * 
	 * @param select
	 */
	public void setSelect(String select) {
		this.select = select;
	}
	/**
	 * 
	 * @param column
	 * @param order
	 */
	public void addOrderby(String column, boolean order) {
		orderList.add(new OrderbyItem(column, order));
	}

	class OrderbyItem {
		/***/
		protected String column;
		/***/
		protected boolean order;
		/***/
		public OrderbyItem(String column, boolean order) {
			this.column = column;
			this.order = order;
		}
	}

	class EntityItem {
		/***/
		protected String name;
		/***/
		@SuppressWarnings("unchecked")
		protected Class cls;
		/**
		 * 
		 * @param name
		 * @param cls
		 */
		@SuppressWarnings("unchecked")
		public EntityItem(String name, Class cls) {
			super();
			this.name = name;
			this.cls = cls;
		}

	}

	/**
	 * 得到orderby语句
	 * 
	 * @param tableAlias
	 *            - 是否需要带表的别名
	 * @return
	 */
	public String getOrderby(boolean tableAlias) {
		if (CollectionUtils.isEmpty(orderList))
			return " ";
		StringBuffer sb = new StringBuffer(" order by ");
		for (OrderbyItem item : orderList) {
			sb.append(marshalOrderName(item.column, tableAlias)).append(" ").append(ORDER_ASC == item.order ? "asc" : "desc").append(", ");
		}
		return sb.delete(sb.length() - 2, sb.length() - 1).toString();
	}

	/**
	 * 得到反序的orderby语句
	 * 
	 * @param tableAlias
	 *            - 是否需要带表的别名
	 * @return
	 */
	public String getReverseOrderby(boolean tableAlias) {
		if (CollectionUtils.isEmpty(orderList))
			return " ";
		StringBuffer sb = new StringBuffer(" order by ");
		for (OrderbyItem item : orderList) {
			sb.append(marshalOrderName(item.column, tableAlias)).append(" ").append(ORDER_DESC == item.order ? "asc" : "desc").append(", ");
		}
		return sb.delete(sb.length() - 2, sb.length() - 1).toString();
	}

	private String marshalOrderName(String name, boolean tableAlias) {
		if (tableAlias)
			return name;
		else {
			int idx = name.indexOf(".");
			return idx == -1 ? name : name.substring(idx + 1);
		}

	}
	/**
	 * 
	 * @return
	 */
	public String getSqlWithoutOrderby() {
		StringBuffer sb = new StringBuffer();
		sb.append(getSelect()).append(" ");

		return sb.toString();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.com.jrj.base.dao.Queryable#getCountStr()
	 */
	public String getCountStr() {
		return "select count(*) " + getRemovedSelect(getSqlWithoutOrderby());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.com.jrj.base.dao.Queryable#getParams()
	 */
	public List<Object> getParams() {
		return new ArrayList<Object>();
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see cn.com.jrj.base.dao.Queryable#getQueryStr()
	 */
	public String getQueryStr() {
		StringBuffer sb = new StringBuffer();
		sb.append(getSqlWithoutOrderby());
		sb.append(getOrderby(true)).append(" ");
		return sb.toString();
	}
}
